package com.zhangyj.impl.actions;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.codehaus.jackson.map.type.TypeFactory;

import com.zhangyj.action.AbstractAction;
import com.zhangyj.action.RequestAction;
import com.zhangyj.action.RequestMethod;
import com.zhangyj.component.grid.HTMLTable;
import com.zhangyj.component.grid.model.ITableModel;
import com.zhangyj.db.DBUtil;
import com.zhangyj.db.NamedPreparedStatement;
import com.zhangyj.entitis.SelectorInfo;
import com.zhangyj.entitis.SystemParam;
import com.zhangyj.impl.ViewName;
import com.zhangyj.impl.component.grid.DefaultHTMLTable;
import com.zhangyj.impl.component.grid.DefaultTableMode;
import com.zhangyj.impl.component.type.GridCol;
import com.zhangyj.impl.component.type.RadioButton;
import com.zhangyj.security.Permission;
import com.zhangyj.util.Pagination;
import com.zhangyj.util.Tools;
@RequestAction(name="selector")
public class Selector extends AbstractAction {

	private static final long serialVersionUID = 3966080818050987800L;
	@RequestMethod
	public String load() throws Exception {
		this.validatePermission(Permission.VIEW);
		com.zhangyj.entitis.SelectorInfo info = SelectorInfo.getInfo(request);
		Pagination pagination = null;

		String param = request.getParameter("param");
		Map<String, Object> paramObj = null;
		if (param != null && param.length() > 0) {
			param = URLDecoder.decode(param, "UTF-8");
			paramObj = Tools.jsonStr2object(param, TypeFactory.mapType(HashMap.class, String.class, Object.class));

		}
		String con = "";
		if (paramObj != null) {
			con = URLEncoder.encode(Tools.object2jsonStr(paramObj), "UTF-8");
		}
		request.setAttribute("param", con);
		if (info.getFilterName() != null) {
			if (paramObj == null) {
				paramObj = new HashMap<String, Object>();
			}
			paramObj.put(info.getFilterName(), "%" + getParameter(info.getFilterName(), "").trim() + "%");
		}

		Connection conn = null;
		try {
			conn = DBUtil.getConnection();
			String sql = info.getSql();
			if (info.isHasPagination()) {
				pagination = new Pagination(request);
				pagination.setPageSize(info.getPageSize());
				pagination.setTotalCount(DBUtil.getIntVal(conn, info.getCountSql(), paramObj));
				sql = pagination.builderSql(sql, info.getOrderField(), info.getOrderTable(), info.isDesc());
				StringBuilder builder = new StringBuilder();
				builder.append("/selector/");
				builder.append(request.getParameter("selector"));
				builder.append(".do?");
				builder.append(SystemParam.getSystemParam(request).toUrlParam());
				if (con != null && con.length() > 0) {
					builder.append("&param=").append(con);
				}
				if (info.getFilterName() != null) {
					builder.append("&").append(info.getFilterName()).append("=").append(URLEncoder.encode(getParameter(info.getFilterName(),""), "UTF-8"));
				}
				pagination.setUrl(builder.toString());
			}

			NamedPreparedStatement nps = DBUtil.getNamedPreparedStatement(conn, sql);

			if (paramObj != null) {
				Iterator<String> keys = paramObj.keySet().iterator();
				while (keys.hasNext()) {
					String key = (String) keys.next();
					Object val = paramObj.get(key);
					if (val instanceof Integer)
						nps.setInt(key, (Integer) val);
					else if (val instanceof Float)
						nps.setFloat(key, (Float) val);
					else
						nps.setString(key, (String) val);
				}
			}

			ResultSet rst = nps.executeQuery();
			ResultSetMetaData rsmd = rst.getMetaData();
			int count = rsmd.getColumnCount();
			int showColCount = 0;
			boolean showCol[] = new boolean[count];
			boolean returnVal[] = new boolean[count];
			String[] cols = new String[count];
			List<GridCol> columns = new ArrayList<GridCol>(count);
			columns.add(new GridCol("选择", 50));
			for (int i = 0; i < count; i++) {
				String col = rsmd.getColumnLabel(i + 1);
				cols[i] = col;
				showCol[i] = !info.isHiddenField(col);
				returnVal[i] = info.isReturnField(col);
				if (showCol[i]) {
					columns.add(new GridCol(info.getLable(col), 0));
					showColCount++;
				}
			}

			List<Object[]> list = new ArrayList<Object[]>();
			List<Map<String, Object>> returnVals = new ArrayList<Map<String, Object>>();
			int rownum = 0;
			while (rst.next()) {
				Object[] vals = new Object[showColCount + 1];
				Map<String, Object> json = new HashMap<String, Object>();
				int index = 1;
				vals[0] = new RadioButton("rowno", String.valueOf(rownum++), false);
				for (int i = 0; i < count; i++) {
					Object o = rst.getObject(i + 1);
					if (showCol[i]) {
						vals[index++] = o;
					}
					if (returnVal[i]) {
						json.put(cols[i], o);
					}
				}
				returnVals.add(json);
				list.add(vals);
			}
			ITableModel tm = new DefaultTableMode(list.iterator(), columns.toArray(new GridCol[columns.size()]));
			HTMLTable ht = new DefaultHTMLTable(tm);
			request.setAttribute("selectInfo", info);
			request.setAttribute("table", ht);
			request.setAttribute("returnValJson", returnVals);
			request.setAttribute(Pagination.ATTRIBUTE_ID, pagination);
			return ViewName.SELECTOR_PAGE;
		} catch (SQLException e) {
			throw e;
		} finally {
			if (conn != null) {
				conn.close();
			}
		}
	}
}
